<?php

/**
 * 访问路由实现及权限判断
 * auth : WQl
 * Class AppRouter
 */
class AppRouter  {

    //get请求
    private $map_get = array();

    //post请求
    private $map_post = array();

    //是否需要登录
    private $get_need_login = array();
    private $post_need_login = array();

    //绑定路由对应方法
    public function get($path, callable $callback, $needLogin = true){
        $this->map_get[$path] = $callback;
        $this->get_need_login[$path] = $needLogin;
    }

    public function post($path, callable $callback, $needLogin = true){
        $this->map_post[$path] = $callback;
        $this->post_need_login[$path] = $needLogin;
    }

    public function onClientMessage(\Workerman\Connection\TcpConnection  $connection,Workerman\Protocols\Http\Request $request )
    {
        $req = new Req();
        // ip
        $req->_from_ip = $connection->getRemoteAddress();
        // 访问方式
        $req->method = $request->method();
        $req->uri = $request->uri();
        $req->path = $request->path();
        $req->header = $request->header();
        $req->params = [];
        if ($req->method == "GET")  $req->params = $request->get();
        if ($req->method == "POST") $req->params = $request->post();
        //本次请求得访问编号，用户bug排查
        $req->request_no = uniqid() .mt_rand(0,999) . mt_rand(0,999) .$req->path;
        $req->request_time = date('Y-m-d H:i:s');
        echo "[$req->request_time] request_no:{$req->request_no};method:{$req->method};path{$req->path};param:".json_encode($req->params, JSON_UNESCAPED_UNICODE).PHP_EOL;
        if (!in_array(strtoupper($req->method),['GET','POST'])){
            //预检请求 如果没有使用cors 跨域 可以关掉
            $connection->send($req->success("ok"));
            return false;
        }
        $req->file = $request->file() ?: [];
        // 登录检查及权限
        $adopt = $this->checkLogin($req,$connection);
        if(!$adopt) return ;
        //执行对应方法
        $action = function ($req){
            return $req->no('not found',404,[]);
        };
        if ($req->method == "GET") $action = $this->map_get[$req->path] ?? $action;
        if ($req->method == "POST") $action = $this->map_post[$req->path] ?? $action;
        $res = call_user_func($action,$req);
        $connection->send($res);
    }

    //登录检查
    public function checkLogin(Req $req,$connection) :bool
    {
        $needLogin = false;
        if($req->method == "GET") $needLogin = $this->get_need_login[$req->path] ?? false;
        if($req->method == "POST") $needLogin = $this->post_need_login[$req->path] ?? false;
        $auth = $req->header['auth'] ?? "";
        if(!$auth) {
            if($needLogin){
                $connection->send($req->no("缺少用户标识",401,[]));
                return false;
            }
            return true;
        }
        //登录验证
        $data = jwt::decode($auth);
        if($data['code'] != 1){
            if(!$needLogin) return true;
            $connection->send($req->no($data['msg']),$data['code']);
            return false;
        }
        $req->memberInfo = (array)$data['data'];
        $req->memberId = $req->memberInfo['id'];
        //防止重复的token
        $platform = $req->getPlatform();
        if(!in_array($platform,[1,2,3])){
            $connection->send($req->no("缺少平台标识"));
            return false;
        }
        $memberId = $req->getMemberId();
        $verify = \m\AppTokenM::getInstance()
            ->where(['platform'=>$platform,'member_id'=>$memberId])
            ->value("token");
        if(!$verify || $verify != $auth) {
            $connection->send($req->no("请使用最新的身份标识",401,[]));
            return false;
        }
        return true;
    }
}